package com.gofaraway.common.exception;

import lombok.Getter;

import java.util.Objects;

/**
 * 异常信息通用枚举
 * 【强制】异常枚举根据业务异常，系统异常，和三方服务异常 往下递增，code不允许重复，
 * see src/main/java/cn/sto/transport/jianmu/common/exception/README.md
 *
 * @author: 1065277
 * @since: 2022-07-28
 **/
@Getter
public enum ErrorCodeEnum {

    /**
     * 正常返回分割线
     */
    ERROR_CODE_00000("00000", "系统正常执行", null), ERROR_CODE_00001("00001", "请求成功", null), ERROR_CODE_00002("00002", "请求异常", null),

    /**
     * 业务异常分割线
     */
    ERROR_CODE_A0001("A0001", "用户端错误", null), ERROR_CODE_A0002("A0002", "用户未登录，无操作权限", null), ERROR_CODE_A0003("A0003", "用户操作权限不足，需要的权限为{rights}", null), ERROR_CODE_A0101("A0101", "{param}:参数不能为空", null), ERROR_CODE_A0102("A0102", "参数不能为空", null), ERROR_CODE_A0103("A0103", "手机号或openid为空!", null), ERROR_CODE_A0112("A0112", "微信消息推送，解析微信消息体为空", "请检查参数是否正常"),

    /**
     * 系统异常分割线
     * 【建议】系统异常最好是可遇见的，并且说明 action 字段需要添加 问题出现是可解决执行的解决方案
     */
    ERROR_CODE_B0001("B0001", "系统维护中，请稍后重试", "系统异常提示统一封装，无需处理"), ERROR_CODE_B0002("B0002", "系统出错啦！", "通用系统异常,根据堆栈信息进行问题定位解决"), ERROR_CODE_B0100("B0100", "{apiName}:接口已废弃", "及时通知调用方，更新为最新的接口"), ERROR_CODE_B0101("B0101", "服务繁忙，请稍候", "系统故障，评估功能等级，及时重启系统，并制定永久解决方案"), ERROR_CODE_B0102("B0102", "数据库插入数据失败", "系统故障，评估功能等级，请排查，并制定永久解决方案"),

    ERROR_CODE_B0103("B0103", "XxlJob定时任务:{apiName},执行异常", "登录xxlJob控制台，查看日志，请根据异常信息定位并解决问题，并及时回补数据"), ERROR_CODE_B0104("B0104", "hbase查询异常:{tableName}不存在", "登录hbase控制台，查看当前表结构是否存在"),
    /**
     * 三方服务异常分割线
     * 【建议】系统异常最好是可遇见的，action字段需要添加  问题出现时可解决执行的解决方案
     */
    ERROR_CODE_C0001("C0001", "百度API调用失败", "接口调用失败,根据提示区分是签名到期还是调用次数上限等原因"), ERROR_CODE_C0101("C0101", "oss生成sign异常", "校验系统编号和签名"), ERROR_CODE_C0102("C0102", "https调用oss请求异常", "排查签名，入参等信息，并且看服务是否和https请求地址通畅"),

    ERROR_CODE_C0104("C0104", "极光推送，微信和APP请求失败!", "排查签名，入参等信息，并且看服务是否和https请求地址通畅"), ERROR_CODE_C0106("C0106", "推送到极光异常!", "请检查连通性"), ERROR_CODE_C0107("C0107", "智慧运输,发送短信通知,出现异常!", "请检查连通性"), ERROR_CODE_C0108("C0108", "推送到微信后台异常！", "请检查连通性"), ERROR_CODE_C0113("C0113", "智慧运营,微信消息,消息推送,异常！", "请检查连通性!"), ERROR_CODE_C0114("C0114", "极光消息推送，解析极光消息体为空", "请检查参数是否正常"), ERROR_CODE_C0115("C0115", "短信消息推送，解析短信消息体为空", "请检查参数是否正常");

    /**
     * 异常错误码
     * 【强制】错误码为字符串类型，共 5 位，分成两个部分：错误产生来源+四位数字编号。
     * 说明：错误产生来源分为 A/B/C，
     * A 表示错误来源于用户，比如参数错误，用户安装版本过低，用户支付超时等问题；
     * B 表示错误来源于当前系统，往往是业务逻辑出错，或程序健壮性差等问题；
     * C 表示错误来源于第三方服务，比如 CDN服务出错，消息投递超时等问题；四位数字编号从 0001 到 9999，大类之间的步长间距预留 100。
     */
    private final String code;

    /**
     * 中文描述
     */
    private final String message;

    /**
     * 解决方案的action
     * 应急预案，解决路径、具体解决方案，运维自动化
     */
    private final String action;

    ErrorCodeEnum(String code, String message, String action) {
        this.code = code;
        this.message = message;
        this.action = action;
    }

    public static ErrorCodeEnum getEnum(String code) {
        ErrorCodeEnum[] types = ErrorCodeEnum.values();
        for (ErrorCodeEnum type : types) {
            if (type.code.equals(code)) {
                return type;
            }
        }
        return null;
    }

    public static String getAction(String code) {
        ErrorCodeEnum errorCodeEnum = getEnum(code);
        if (Objects.nonNull(errorCodeEnum)) {
            return errorCodeEnum.getAction();
        }
        return null;
    }

}

